﻿#include "authorizationguard.h"

#include <QCoreApplication>
#include <QFile>
#include <qjsonwebtoken.h>
#include <qmotherboardinfoprovider.h>
#include <QDebug>

QMutex AuthorizationGuard::mutex;
AuthorizationGuard* AuthorizationGuard::instance = nullptr;

AuthorizationGuard &AuthorizationGuard::getInstance()
{
    if (instance == nullptr) {
        QMutexLocker locker(&mutex);
        if (instance == nullptr) {
            instance = new AuthorizationGuard();
        }
    }
    return *instance;
}

void AuthorizationGuard::deleteInstance()
{
    if (instance != nullptr) {
        delete instance;
        instance = nullptr;
    }
}

void AuthorizationGuard::setSecretKey(QString &key)
{
    secretKey = key;
}

bool AuthorizationGuard::isAuthorised()
{
    if(authorised){
        return authorised;
    }else{
        if(isFirstVerify){
            isFirstVerify = false;
            authorised = verify();
        }
        return authorised;
    }
}

QString AuthorizationGuard::getLatestHintText() const
{
    return latestHintText;
}

AuthorizationGuard::AuthorizationGuard(QObject *parent) : QObject(parent)
{
    isFirstVerify = true;
    authorised = false;
    secretKey = "sanshi811";
    authorizationKeyFilePath = QCoreApplication::applicationDirPath() + "/authorization.key";
    authorizationLicenseFilePath = QCoreApplication::applicationDirPath() + "/authorization.license";
    latestHintText = "未授权";
}

AuthorizationGuard::~AuthorizationGuard()
{

}

bool AuthorizationGuard::verify()
{
    //获取设备信息码
    QString deviceCode;
    QMotherboardInfoProvider provider;
    QList<QMotherboardInfoProvider::MotherboardDetails> details = provider.getAllMotherboardDetails();
    if(details.size() == 0){
        authorised = false;
        latestHintText = "未知设备标识";
        return false;
    }
    deviceCode = details[0].serialNumber;
    authorizationKey = deviceCode;

    if(!readAuthorizationLicenseFile()){
        latestHintText = "许可文件读取失败";
        writeAuthorizationKeyFile();
        return false;
    }

    if(authorizationLicense.isEmpty() ){
        latestHintText = "许可文件解析异常";
        writeAuthorizationKeyFile();
        return false;
    }

    QJsonWebToken jwt;
    jwt.setSecret(secretKey);
    jwt.setAlgorithmStr("HS256");

    jwt.appendClaim("key-1",authorizationKey);
    if(jwt.getToken() == authorizationLicense){
        latestHintText = "校验成功";
        return true;
    }else{
        latestHintText = "校验失败";
        writeAuthorizationKeyFile();
        return false;
    }
}

bool AuthorizationGuard::generate()
{
    if(!readAuthorizationKeyFile()){
        latestHintText = "key文件读取失败";
        return false;
    }

    if(authorizationKey.isEmpty() ){
        latestHintText = "key文件解析异常";
        return false;
    }

    QJsonWebToken jwt;
    jwt.setSecret(secretKey);
    jwt.setAlgorithmStr("HS256");

    jwt.appendClaim("key-1",authorizationKey);

    authorizationLicense = jwt.getToken();

    if(authorizationLicenseFilePath.isEmpty()){
        latestHintText = "许可文件路径为空";
        return false;
    }

    if(writeAuthorizationLicenseFile()){
        latestHintText = "许可生成成功";
        return true;
    }else{
        latestHintText = "许可文件写入失败";
        return false;
    }
}

void AuthorizationGuard::writeAuthorizationKeyFile()
{
    QFile file(authorizationKeyFilePath);
    if(file.open(QFile::WriteOnly)){
        file.write(authorizationKey.toLatin1(),authorizationKey.toLatin1().size());
        file.close();
    }else{
        qCritical() << "授权Key文件打开失败";
    }
}

bool AuthorizationGuard::writeAuthorizationLicenseFile()
{
    QFile file(authorizationLicenseFilePath);
    if(file.open(QFile::WriteOnly)){
        file.write(authorizationLicense.toLatin1(),authorizationLicense.toLatin1().size());
        file.close();
        return true;
    }else{
        return false;
    }
}

bool AuthorizationGuard::readAuthorizationKeyFile()
{
    QFile file(authorizationKeyFilePath);
    if(file.open(QFile::ReadOnly)){
        authorizationKey = file.readAll();
        file.close();
        return true;
    }
    return false;
}

bool AuthorizationGuard::readAuthorizationLicenseFile()
{
    QFile file(authorizationLicenseFilePath);
    if(file.open(QFile::ReadOnly)){
        authorizationLicense = file.readAll();
        file.close();
        return true;
    }
    return false;
}

void AuthorizationGuard::setAuthorizationLicense(const QString &value)
{
    authorizationLicense = value;
}

bool AuthorizationGuard::verifyAuthorizationLicense()
{
    return verify();
}

bool AuthorizationGuard::generateAuthorizationLicense()
{
    return generate();
}

void AuthorizationGuard::setAuthorizationKey(const QString &value)
{
    authorizationKey = value;
}

void AuthorizationGuard::setAuthorizationLicenseFilePath(const QString &value)
{
    authorizationLicenseFilePath = value;
}

void AuthorizationGuard::setAuthorizationKeyFilePath(const QString &value)
{
    authorizationKeyFilePath = value;
}
